/*
Copyright (C) 2022-2024 Inspur Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package controller

import (
	"github.com/emicklei/go-restful"

	"did-service/auth"
	"did-service/bean/model"
	"did-service/bean/param"
	"did-service/common/constant"
	"did-service/common/http"
	"did-service/common/uuid"
	"did-service/service"
)

// ApplyPresentation VP申请
func (dc *DidController) ApplyPresentation(req *restful.Request, resp *restful.Response) {
	currentWalletId := auth.GetCurrentWalletId(req)
	userType := auth.GetCurrentUserType(req)
	if userType != constant.UserTypePerson && userType != constant.UserTypeEnterprise {
		http.Failed(resp, "此用户无法申请!")
		return
	}

	var para param.ApplyPresentationParam
	if err := req.ReadEntity(&para); err != nil {
		log.Errorf("read entity error: %v", err)
		http.Failed(resp, "读取参数错误!")
		return
	}
	//验证参数
	if ok, errStr := service.ValidatePara(para); !ok {
		http.Failed(resp, errStr)
		return
	}
	//校验凭证
	ok, info, credDetail, err := dc.srv.ValidateCredential(currentWalletId, para.CredId)
	if err != nil {
		log.Errorf("error: %v", err)
		http.Failed(resp, "验证凭证失败!")
		return
	}
	if !ok {
		http.Failed(resp, info)
		return
	}

	//校验披露属性是否与凭证对应
	ok, info, err = dc.srv.ValidateClaims(para.Claims, para.CredId)
	if err != nil {
		log.Errorf("error: %v", err)
		http.Failed(resp, "验证Claims失败!")
		return
	}
	if !ok {
		http.Failed(resp, info)
		return
	}
	vpId := uuid.Generate()
	//生成可验证凭证
	if err = dc.srv.GeneratePresentation(currentWalletId, vpId, credDetail.Credential, &para); err != nil {
		log.Errorf("err: %v", err)
		http.Failed(resp, "生成VP失败!")
		return
	}
	log.Infof("generate VP, Id: %s", vpId)

	vpResp := model.PresentationResponse{RequestId: vpId}
	http.OkWithData(resp, "成功", vpResp)
}

// PresentationList 用户VP列表
func (dc *DidController) PresentationList(req *restful.Request, resp *restful.Response) {
	currentWalletId := auth.GetCurrentWalletId(req)
	userType := auth.GetCurrentUserType(req)
	if userType != constant.UserTypePerson && userType != constant.UserTypeEnterprise {
		http.Failed(resp, "此用户无法获取VP列表!")
		return
	}

	para := &param.ListPresentationParam{}
	service.ParseQueryParam(req, para)

	credList, err := dc.srv.QueryPresentationList(currentWalletId, para)
	if err != nil {
		log.Errorf("error: %v", err)
		http.Failed(resp, "获取VP列表失败!")
		return
	}
	http.OkWithData(resp, "成功", credList)
}

func (dc *DidController) PresentationDetail(req *restful.Request, resp *restful.Response) {
	walletId := auth.GetCurrentWalletId(req)
	userType := auth.GetCurrentUserType(req)
	if userType != constant.UserTypePerson && userType != constant.UserTypeEnterprise {
		http.Failed(resp, "此用户无法获取VP明细!")
		return
	}

	presentationId := req.PathParameter("presentationId")
	if presentationId == "" {
		log.Errorf("presentation id can not be empty!")
		http.Failed(resp, "VP编号不能为空!")
		return
	}

	data, err := dc.srv.QueryPresentationDetail(walletId, presentationId)
	if err != nil {
		log.Errorf("err: %s", err)
		http.Failed(resp, "查询失败！")
		return
	}
	http.OkWithData(resp, "成功", data)
}
